#pragma once 
#include<iostream>
#include<string>
#include<fstream>
#include<sys/types.h>
#include<unistd.h>
#include <cstdarg>
#include <pthread.h>
#include"LockGuard.hpp"
bool is_save = false;
const std::string logname = "log.txt";
void SaveFile(const std::string& filename, const std::string& message);
//1. 日志等级
enum{
    DEBUG = 0,
    INFO,
    ERROR,
    FATAL
};
std::string GetLevelString(int level)
{
    switch(level)
    {
        case DEBUG:
            return "Debug";
        case INFO:
            return "Info";
        case ERROR:
            return "Error";
        case FATAL:
            return "Fatal";
        default:
            return "Unknow";
            
    }
}
//2. 日志时间
std::string GetTimeString()
{
    time_t curr_time = time(nullptr);
    struct tm* format_time = localtime(&curr_time);
    if(format_time == nullptr)
        return "None";
    char time_buffer[1024];
    snprintf(time_buffer,sizeof(time_buffer),"%d-%d-%d %d:%d:%d",
    format_time->tm_year + 1990,
    format_time->tm_mon + 1,
    format_time->tm_mday,
    format_time->tm_hour,
    format_time->tm_min,
    format_time->tm_sec    
    );
    return time_buffer;
}

//3. 日志格式化
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
#define LOG(level, format, ...)                                                \
    do                                                                         \
    {                                                                          \
        LogMessage(__FILE__, __LINE__, is_save, level, format, ##__VA_ARGS__); \
    } while (0)
void LogMessage(std::string filename,int line,bool is_save,int level,const char* format,...)
{
    std::string levelstr = GetLevelString(level);
    std::string timestr = GetTimeString();
    pid_t selfid = getpid();
    char buffer[1024];


    va_list arg;
    va_start(arg,format);
    vsnprintf(buffer,sizeof(buffer),format,arg);
    va_end(arg);

    std::string message = "[" + timestr + "]" + "[" + levelstr + "]" +
                          "[" + std::to_string(selfid) + "]" +
                          "[" + filename + "]" + "[" + std::to_string(line) + "] " + buffer + "\n";
    LockGuard lockguard(&lock);//加锁
    if(!is_save)
    {
        std::cout<<message;
    }
    else
        SaveFile(logname,message);
}

#define EnableFile()  \
do{                   \
    is_save = true;   \
}while(0)
#define DisableFile() \
do{                   \
    is_save = false;  \
}while(0)


//4. 日志文件保存
void SaveFile(const std::string& filename, const std::string& message)
{
    std::ofstream out(filename,std::ios::app);
    if(!out.is_open())
    {
        return ;
    }
    out<<message;
    out.close();
}
